/*
 *  CS202 - Spring 2009">
 *  Professor: Dr. Michael Peterson">
 *  Student: Deylo Woo (dwoo711@gmail.com) ">
 */
package project_3;

import javax.swing.*;
import java.awt.*;
import java.util.LinkedList;

public class GamePanel extends JPanel {

    private int _height;
    private int _width;
    private Cannon _cannon;
    private LinkedList<Missile> _missiles;
    private LinkedList<Ship> _ships;

    public GamePanel() {
        super();
        _cannon = new Cannon(390, 680, 20, 20, 0, 0, Color.BLUE);
        _missiles = new LinkedList<Missile>();
        _ships = new LinkedList<Ship>();

        this.setBackground(Color.ORANGE);
        this.setVisible(true);
    //StartNewGame();
    }

    public GamePanel(int width, int height) {
        this();
        _height = height;
        _width = width;
    }

    public void Move() {
        //move cannons
        _cannon.Move(getHeight(), getWidth());
        //Move all missiles
        for (int x = 0; x < _missiles.size(); x++) {
            Missile _msl = _missiles.get(x);
            _msl.Move(getHeight(), getWidth());
            if (CheckForOutOfBounds(_msl)) {
                _missiles.remove(x);
            }
        }
        //Move all space ships

        if (_ships.size() < 500) {
            _ships.add(MakeShip());
        }
        for (int x = 0; x < _ships.size(); x++) {
            Ship _shp = _ships.get(x);
            _shp.Move(getHeight(), getWidth());
            if (CheckForOutOfBounds(_shp)) {
                _ships.remove(x);
            }
        }
       CheckForCollision();
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.ORANGE);
        g.fillRect(0, 0, this.getWidth(), this.getHeight());

        getCannon().paint(g);
        for (Missile _msl : _missiles) {
            _msl.paint(g);
        }
        for (Ship _shp : _ships) {
            _shp.paint(g);
        }
    }

    //Methods
    public void FireMissile() {
        Missile _missile;
        _missile = new Missile(_cannon.getXCoord() + 10, _cannon.getYCoord(), 10, 3, -5, 0, Color.BLACK);
        _missiles.add(_missile);
    }

    public void MoveLeft() {
        if (_cannon.getXCoord() > 0) {
            _cannon.setXCoord(_cannon.getXCoord() - 5);
        }
    }

    public void MoveRight() {
        if (_cannon.getXCoord() < _width - _cannon.getWidth()) {
            _cannon.setXCoord(_cannon.getXCoord() + 5);
        }
    }

    public boolean CheckForOutOfBounds(MovingObject mvObj) {
        boolean isOuOfB = false;
        if (mvObj.getXCoord() < (0 - mvObj.getRun())) {
            isOuOfB = true;
        } else if (mvObj.getXCoord() > (_width - mvObj.getWidth())) {
            isOuOfB = true;
        }
        if (mvObj.getYCoord() < (0 - mvObj.getRise())) {
            isOuOfB = true;
        } else if (mvObj.getYCoord() > (_height - mvObj.getHeight())) {
            isOuOfB = true;
        }
        return isOuOfB;
    }

    public Ship MakeShip() {
        Color _Shipcolor = GetRandomColor();
        int _Shipheight = (int) ((Math.random() * 20) + 10); //range from 10-20
        int _Shipwidth = (int) ((Math.random() * 100) + 20);
        int _Shiprise = (int) 0;
        int _ShipyCoord = (int) (Math.random() * 500);
        int _Shiprun = (int) ((Math.random() * 7) + 2);
        int _ShipxCoord = 1;
        if (((int) ((Math.random() * 2) + 1) == 1)) {
            _ShipxCoord = 1;
        } else {
            _ShipxCoord = getWidth() - _Shipwidth;
            _Shiprun = -_Shiprun;
        }

        Ship _ship = new Ship(_ShipxCoord, _ShipyCoord, _Shipheight, _Shipwidth, _Shiprise, _Shiprun, _Shipcolor);
        return _ship;
    }

    private Color GetRandomColor() {
        int red = (int) (Math.random() * 255);
        int green = (int) (Math.random() * 255);
        int blue = (int) (Math.random() * 255);
        return new Color(red, green, blue);
    }

    public boolean CheckForCollision2() {
        boolean _hasCollided = false;
        LinkedList<Ship> _removeShipList = new LinkedList<Ship>();
        LinkedList<Missile> _removeMissileList = new LinkedList<Missile>();

        //iterate through all ships and missiles
        for (Ship _shp : _ships) {
            for (Missile _msl : _missiles) {
                if (_msl.getXCoord() >= _shp.getXCoord() &&
                        _msl.getXCoord() <= _shp.getXCoord() + _shp.getWidth() &&
                        _msl.getYCoord() >= _shp.getYCoord() &&
                        _msl.getYCoord() <= _shp.getYCoord() + _shp.getHeight()) {

                    _removeMissileList.add(_msl);
                    _removeShipList.add(_shp);

                    _hasCollided = true;
                }
            }
        }

        for (int x = 0; x < _removeMissileList.size(); x++) {
            _missiles.remove(x);
        }
        for (int x = 0; x < _removeShipList.size(); x++) {
            _ships.remove(x);
        }


        return _hasCollided;
    }

    public boolean CheckForCollision() {
        boolean _hasCollided = false;
        //iterate through all ships and missiles

        for (int x = 0; x < _missiles.size(); x++) {
            for (int y = 0; y < _ships.size(); y++) {
                Missile _msl = _missiles.get(x);
                Ship _shp = _ships.get(y);
                if (_msl != null && _shp != null) {
                    //check for x,y collision
                    if (_msl.getXCoord() >= _shp.getXCoord() &&
                            _msl.getXCoord() <= _shp.getXCoord() + _shp.getWidth() &&
                            _msl.getYCoord() >= _shp.getYCoord() &&
                            _msl.getYCoord() <= _shp.getYCoord() + _shp.getHeight()) {
                        _ships.remove(_shp);
                        _missiles.remove(_msl);
                        _hasCollided = true;
                        break;
                    }
                }
            }
        }
        return _hasCollided;
    }

//Property access
    /**
     * @return the _height
     */
    public int getHeight() {
        return _height;
    }

    /**
     * @param height the _height to set
     */
    public void setHeight(int height) {
        this._height = height;
    }

    /**
     * @return the _width
     */
    public int getWidth() {
        return _width;
    }

    /**
     * @param width the _width to set
     */
    public void setWidth(int width) {
        this._width = width;
    }

    /**
     * @return the _cannon
     */
    public MovingObject getCannon() {
        return _cannon;
    }

    /**
     * @param cannon the _cannon to set
     */
    public void setCannon(Cannon cannon) {
        this._cannon = cannon;
    }
}
